package cc.rengu.igas.share.core.service.trans;

import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.common.enums.FeeTypeEnum;
import cc.rengu.igas.share.common.enums.RespCodeEnum;
import cc.rengu.igas.share.core.model.UpqcPayerInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.igas.share.core.service.base.NoticeService;
import cc.rengu.igas.share.facade.bean.UpqcCouponInfo;
import cc.rengu.igas.share.facade.request.UpqcPayResultNoticeRequest;
import cc.rengu.igas.share.facade.response.UpqcPayResultNoticeResponse;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.*;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 银联二维码收款交易结果通知服务
 */
public class UpqcQrCodePayNoticeService extends NoticeService implements TransCustomImpl {

    @Override
    protected Object bizBeforeCust() throws Exception {
        UpqcPayResultNoticeRequest upqcPayResultNoticeRequest = new UpqcPayResultNoticeRequest();
        ConvertUtil.convertOutput(upqcPayResultNoticeRequest);
        return upqcPayResultNoticeRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        UpqcPayResultNoticeRequest upqcPayResultNoticeRequest = (UpqcPayResultNoticeRequest) request;
        UpqcPayResultNoticeResponse upqcPayResultNoticeResponse = new UpqcPayResultNoticeResponse();
        upqcPayResultNoticeResponse.setHeader(upqcPayResultNoticeRequest.getHeader());
        BizResponse bizResponse = new BizResponse();
        String instId = upqcPayResultNoticeRequest.getHeader().getInstId();
        String payInfo = upqcPayResultNoticeRequest.getPayerInfoStr();
        UpqcPayerInfo payerInfo = (UpqcPayerInfo) convertKvStr2Bean(payInfo.substring(1, payInfo.length() - 1), UpqcPayerInfo.class);
        rglog.debug("payerInfo:<{}>", JSON.toJSONString(payerInfo));

        /* 根据订单号获取原支付交易订单信息 */
        OrderService orderService = new OrderServiceImpl();
        OrderInfo orderInfo = orderService.selectOrderInfoBySysSeqNum(instId, upqcPayResultNoticeRequest.getOrderId());
        if (null == orderInfo) {
            rglog.error("机构<{}>没有对应的银联二维码订单号<{}>信息", instId, upqcPayResultNoticeRequest.getOrderId());
            throw new BizException(RespCodeEnum.ORDER_NOT_EXIST.getRespCode(), RespCodeEnum.ORDER_NOT_EXIST.getRespDesc());
        }
        UserOrderInfo userOrderInfo = orderInfo.getUserOrderInfo();
        List<MchntOrderInfo> mchntOrderInfoList = orderInfo.getMchntOrderInfoList();
        Optional<PayOrderInfo> payOrderInfoOpt = orderInfo.getPayOrderInfoList().stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.UPQC.getChannelType())).findFirst();
        if (!payOrderInfoOpt.isPresent()) {
            rglog.error("机构<{}>没有对应的银联二维码订单号<{}>信息", instId, upqcPayResultNoticeRequest.getOrderId());
            throw new BizException(RespCodeEnum.ORDER_NOT_EXIST.getRespCode(), RespCodeEnum.ORDER_NOT_EXIST.getRespDesc());
        }
        PayOrderInfo payOrderInfo = payOrderInfoOpt.get();
        if (TransStatusEnum.TRANS_SUCC.getStatus().equals(payOrderInfo.getTransStatus()) &&
                (BizStatusEnum.FINISH.getStatus().equals(payOrderInfo.getBizStatus()) ||
                        BizStatusEnum.REFUND.getStatus().equals(payOrderInfo.getBizStatus()) ||
                        BizStatusEnum.PART_REFUND.getStatus().equals(payOrderInfo.getBizStatus()) ||
                        BizStatusEnum.CONFIRM.getStatus().equals(payOrderInfo.getBizStatus()))) {
            rglog.error("订单已成功，不处理直接返回结果");
            upqcPayResultNoticeResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            upqcPayResultNoticeResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            bizResponse.setResult(upqcPayResultNoticeResponse);
            bizResponse.setRspSysId(AppParamConstant.IGAS);
            bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            return bizResponse;
        }

        /* 更新用户订单表 */
        /* 判断原订单表中的订单金额是否为空或0.00,若是则对三个订单表中的订单金额进行赋值 */
        if (StringUtil.isEmptyOrNull(userOrderInfo.getOrderAmt()) || AmountUtil.compare(userOrderInfo.getOrderAmt(), "0.00") == 0) {
            if (StringUtil.isEmptyOrNull(upqcPayResultNoticeRequest.getOrigTxnAmt())) {
                userOrderInfo.setOrderAmt(upqcPayResultNoticeRequest.getOrderAmt());
                userOrderInfo.setNeedPayAmt(upqcPayResultNoticeRequest.getOrderAmt());
            } else {
                userOrderInfo.setOrderAmt(upqcPayResultNoticeRequest.getOrigTxnAmt());
                userOrderInfo.setNeedPayAmt(upqcPayResultNoticeRequest.getOrigTxnAmt());
            }
        }
        userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
        userOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        userOrderInfo.setOrderAmt(upqcPayResultNoticeRequest.getOrderAmt());
        userOrderInfo.setRealPayAmt(upqcPayResultNoticeRequest.getOrderAmt());
        userOrderInfo.setNeedPayAmt(upqcPayResultNoticeRequest.getOrderAmt());
        userOrderInfo.setRealDiscountAmt("0.00");

        /* 更新支付订单表 */
        payOrderInfo.setRealPayAmt(upqcPayResultNoticeRequest.getOrderAmt());
        if (StringUtil.isEmptyOrNull(payOrderInfo.getOrderAmt()) || AmountUtil.compare(payOrderInfo.getOrderAmt(), "0.00") == 0) {
            if (StringUtil.isEmptyOrNull(upqcPayResultNoticeRequest.getOrigTxnAmt())) {
                payOrderInfo.setOrderAmt(upqcPayResultNoticeRequest.getOrderAmt());
            } else {
                payOrderInfo.setOrderAmt(upqcPayResultNoticeRequest.getOrigTxnAmt());
            }
        }
        if (null == payerInfo) {
            payOrderInfo.setPayerAcctType(AcctTypeEnum.ALL.getAcctType());
        } else {
            String issCode = getSysParamIssCode(instId);
            if (StringUtil.isEmptyOrNull(issCode)) {
                payOrderInfo.setPayerAcctType(AcctTypeEnum.ALL.getAcctType());
            } else {
                if ("01".equals(payerInfo.getCardAttr())) {
                    /*借记卡，区分本行和他行借记卡*/
                    if (issCode.equals(payerInfo.getIssCode())) {
                        payOrderInfo.setPayerAcctType(AcctTypeEnum.BANK_DEBIT.getAcctType());
                    } else {
                        payOrderInfo.setPayerAcctType(AcctTypeEnum.OTHER_DEBIT.getAcctType());
                    }
                } else if ("02".equals(payerInfo.getCardAttr())) {
                    if (issCode.equals(payerInfo.getIssCode())) {
                        payOrderInfo.setPayerAcctType(AcctTypeEnum.BANK_CREDIT.getAcctType());
                    } else {
                        payOrderInfo.setPayerAcctType(AcctTypeEnum.OTHER_CREDIT.getAcctType());
                    }
                } else {
                    payOrderInfo.setPayerAcctType(AcctTypeEnum.ALL.getAcctType());
                }
            }
            payOrderInfo.setPayerAcctInfo(payerInfo.getAccNo());
            payOrderInfo.setPayerRemark(payerInfo.getName());
        }
        payOrderInfo.setOrderAmt(upqcPayResultNoticeRequest.getOrderAmt());
        payOrderInfo.setRealPayAmt(upqcPayResultNoticeRequest.getOrderAmt());
        /*存储通道优惠金额*/
        payOrderInfo.setChannelDiscountAmt("0.00");
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
        payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
        payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        payOrderInfo.setSettleDate(upqcPayResultNoticeRequest.getSettleDate());
        /*银联返回付款凭证号*/
        payOrderInfo.setChannelOrderId(upqcPayResultNoticeRequest.getVoucherNum());
        /*银联返回对账唯一key*/
        payOrderInfo.setChannelSeqNum(upqcPayResultNoticeRequest.getSettleKey());
        payOrderInfo.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        payOrderInfo.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());

        /* 更新商户订单表：处理商户清算金额 商户订单表中实际清算金额=实际清算金额-支付宝优惠金额*/
        MchntService mchntService = new MchntServiceImpl();
        String mchntFeeType = getMchntFeeType(payerInfo);
        for (MchntOrderInfo mchntOrderInfo : mchntOrderInfoList) {
            if (StringUtil.isEmptyOrNull(mchntOrderInfo.getOrderAmt()) || AmountUtil.compare(mchntOrderInfo.getOrderAmt(), "0.00") == 0) {
                if (StringUtil.isEmptyOrNull(upqcPayResultNoticeRequest.getOrigTxnAmt())) {
                    mchntOrderInfo.setOrderAmt(upqcPayResultNoticeRequest.getOrderAmt());
                    mchntOrderInfo.setRealSettleAmt(upqcPayResultNoticeRequest.getOrderAmt());
                } else {
                    mchntOrderInfo.setOrderAmt(upqcPayResultNoticeRequest.getOrigTxnAmt());
                    mchntOrderInfo.setRealSettleAmt(upqcPayResultNoticeRequest.getOrigTxnAmt());
                }
            }
            /* 判断是否参与了银联或者商户营销 */
            if (!StringUtil.isEmptyOrNull(upqcPayResultNoticeRequest.getCouponInfo())) {
                List<UpqcCouponInfo> upqcCouponInfoList = JSON.parseArray(upqcPayResultNoticeRequest.getCouponInfo(), UpqcCouponInfo.class);
                for (UpqcCouponInfo upqcCouponInfo : upqcCouponInfoList) {
                    if ("00010000".equals(upqcCouponInfo.getSpnsrId())) {
                        rglog.info("用户支付享受了银联的营销活动，减免了:{}元", AmountUtil.changeF2Y(upqcCouponInfo.getOffstAmt()));
                        payOrderInfo.setChannelDiscountAmt(AmountUtil.changeF2Y(upqcCouponInfo.getOffstAmt()));
                    } else if (mchntOrderInfo.getMchntNo().equals(upqcCouponInfo.getSpnsrId())) {
                        rglog.info("用户支付享受了商户的营销活动，减免了:{}元", AmountUtil.changeF2Y(upqcCouponInfo.getOffstAmt()));
                        mchntOrderInfo.setCustomerMarketAmt(AmountUtil.changeF2Y(upqcCouponInfo.getOffstAmt()));
                        mchntOrderInfo.setRealSettleAmt(AmountUtil.subtraction(mchntOrderInfo.getRealSettleAmt(), mchntOrderInfo.getCustomerMarketAmt()));
                    }
                }
                String userPrePayDistAmt = StringUtil.isEmptyOrNull(userOrderInfo.getRealDiscountAmt()) ? "0.00" : userOrderInfo.getRealDiscountAmt();
                String channelDistAmt = AmountUtil.addition(payOrderInfo.getChannelDiscountAmt(), mchntOrderInfo.getCustomerMarketAmt());
                userOrderInfo.setRealDiscountAmt(AmountUtil.addition(userPrePayDistAmt, channelDistAmt));
                userOrderInfo.setRealPayAmt(AmountUtil.subtraction(userOrderInfo.getNeedPayAmt(), channelDistAmt));
            }
            /*商户订单状态*/
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            mchntOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            /*商户订单金额*/
            mchntOrderInfo.setOrderAmt(upqcPayResultNoticeRequest.getOrderAmt());
            /*商户实际清算金额*/
            mchntOrderInfo.setRealSettleAmt(upqcPayResultNoticeRequest.getOrderAmt());
            /*商户订单更新时间*/
            mchntOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            /* 计算商户手续费 */
            boolean calcResult = mchntService.calcMchntFee(mchntOrderInfo, mchntFeeType);
            if (!calcResult) {
                rglog.warn("计算商户<{}>手续费失败，日终批量再进行商户手续费计算!", mchntOrderInfo.getMchntNo());
            }
            String realSettleFlag = mchntService.getRealSettleFlag(mchntOrderInfo.getMchntNo(), mchntOrderInfo.getBizProdCode(), mchntOrderInfo.getBizSceneType(), mchntOrderInfo.getRealSettleAmt());
            mchntOrderInfo.setRealSettleFlag(realSettleFlag);
        }
        GlobalTransUtil.setCacheValue(TransCacheConstant.MCHNT_ORDER_INFO_LIST, mchntOrderInfoList);

        /* 更新订单信息 */
        if (!orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfo)) {
            rglog.error("更新支付订单状态失败");
            throw new BizException(RespCodeEnum.ORDER_UPDATE_ERROR.getRespCode(), RespCodeEnum.ORDER_UPDATE_ERROR.getRespDesc());
        }

        //调用通道接口
        if (null == txnInfo.getChannelCallCfgList() || txnInfo.getChannelCallCfgList().isEmpty()) {
            rglog.error("<{}-{}>交易未配置交易通道服务调用配置信息！", txnInfo.getSrcTxnAuthCfg().getTxnNum(), txnInfo.getSrcTxnAuthCfg().getTxnName());
            throw new BizException(RespCodeEnum.TRANS_NOT_SUPPORT.getRespCode(), RespCodeEnum.TRANS_NOT_SUPPORT.getRespDesc());
        }
        List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item ->
                item.getCallIndex().equals(ChannelBaseService.FIRST_CHANNEL_CALL_INDEX)).collect(Collectors.toList());
        ChannelCallCfg channelCallCfg = channelCallSceneDiscern(upqcPayResultNoticeRequest, channelCallCfgList);
        Class channelClasz = Class.forName(channelCallCfg.getCallChannelImpl());
        ChannelBaseService channelBaseService = (ChannelBaseService) channelClasz.newInstance();
        channelBaseService.callService(txnInfo, orderInfo, channelCallCfg.getBizScene(), request);

        /* 更新商户累计限额 */
        mchntService.updateMchntTransLimit(mchntOrderInfoList);

        /* 组装成功应答报文 */
        bizResponse.setResult(upqcPayResultNoticeResponse);
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        UpqcPayResultNoticeResponse upqcPayResultNoticeResponse = (UpqcPayResultNoticeResponse) bizResponse.getResult();
        ConvertUtil.convertInput(upqcPayResultNoticeResponse);
    }

    /**
     * 获取商户手续费费率类型
     *
     * @param payerInfo 付款方账号信息
     * @return 商户费率类型
     */
    private String getMchntFeeType(UpqcPayerInfo payerInfo) {
        String feeType;
        /*获取费率类型*/
        if (null == payerInfo) {
            /*商户手续费默认贷记卡*/
            feeType = FeeTypeEnum.UPQR_CR.getFeeType();
        } else {
            if (StringUtil.isEmptyOrNull(payerInfo.getCardAttr())) {
                /*商户手续费默认贷记卡*/
                feeType = FeeTypeEnum.UPQR_CR.getFeeType();
            } else {
                if ("01".equals(payerInfo.getCardAttr())) {
                    feeType = FeeTypeEnum.UPQR_DR.getFeeType();
                } else {
                    feeType = FeeTypeEnum.UPQR_CR.getFeeType();
                }
            }
        }
        return feeType;
    }

    /**
     * 获取发卡机构代码
     *
     * @param instId 多法人标识
     * @return 发卡机构代码
     * @throws Exception 异常
     */
    private String getSysParamIssCode(String instId) throws Exception {
        String issCode = null;
        /*查询系统参数表*/
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, "UPQC_SYS_PARAM", "UPQC_ISSUR_CODE");
        if (null != sysParam && null != sysParam.getParamValue()) {
            issCode = sysParam.getParamValue();
        }
        return issCode;
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        /* 业务场景类型：00-担保支付或购买卡卷场景，01-商户实时入账场景，02-非商户实时入账场景，03-特殊计费场景 */
        String bizScene = "00";
        List<MchntOrderInfo> mchntOrderInfoList = (List<MchntOrderInfo>) GlobalTransUtil.getCacheValue(TransCacheConstant.MCHNT_ORDER_INFO_LIST);
        if (null != mchntOrderInfoList && !"00".equals(mchntOrderInfoList.get(0).getBizSceneType()) &&
                !"01".equals(mchntOrderInfoList.get(0).getBizSceneType()) && !"02".equals(mchntOrderInfoList.get(0).getBizSceneType())) {
            if (AppParamConstant.YES.equals(mchntOrderInfoList.get(0).getRealSettleFlag())) {
                /* 商户实时入账场景 */
                bizScene = "01";
            } else if (!"0".equals(mchntOrderInfoList.get(0).getFeeInputMode())) {
                /* 非特殊计费场景 */
                bizScene = "02";
            } else {
                /* 特殊计费场景 */
                bizScene = "03";
            }
        }
        String finalBizScene = bizScene;
        Optional<ChannelCallCfg> channelCallCfgOpt = channelCallCfgList.stream().filter(item -> item.getBizScene().equals(finalBizScene)).findFirst();
        return channelCallCfgOpt.orElse(null);
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return CheckResultEnum.PASSED;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        return null;
    }
}
